package homework_java.eg;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeSet;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class DemoCollection {
	@SuppressWarnings("unchecked")
	public static void main(String[] args){
		DemoCollection.testList();
		DemoCollection.testSet();
		DemoCollection.testMap();
		
		
		HashMap<String, Person> map = new HashMap<String, Person>();
		Person p1 = new Person("000101", "Tom");
		Person p2 = new Person("000103", "Ann");
		Person p3 = new Person("000102", "Ethan");
		map.put(p1.id, p1);
		map.put(p2.id, p2);
		map.put(p3.id, p3);
		System.out.println("******Testing Map<String, Person>.EntrySet()******");
		DemoCollection.traverseMapViaIterator(map);
		System.out.println("******Testing Map<String, Person>.values()******");
		DemoCollection.traverseCollectionViaIterator(map.values());
		System.out.println("******Testing Map<String, Person>.keySet()******");
		DemoCollection.traverseCollectionViaIterator(map.keySet());
		System.out.println("******Testing HashSet<Person>******");
		HashSet<Person> set = new HashSet<Person>();
		set.add(p1);
		set.add(p2);
		set.add(p3);
		DemoCollection.traverseCollectionViaIterator(set);
		Person p4 = new Person("100104", "Jason");
		set.add(p4);
		//����
		ArrayList<Person> pList = new ArrayList<Person>();
		pList.addAll(set);
		Object[] personArray = pList.toArray();
		System.out.println("Length of array: " + personArray.length);
		System.out.println(personArray[0] instanceof Person);
		
		Collections.sort(pList);
		//Collections.sort(pList, new ComparatorViaPersonId());
		System.out.println("******ArrayList<Person>******");
		DemoCollection.traverseCollectionViaIterator(pList);
		set.clear();
		set.addAll(pList);
		System.out.println("******HashSet<Person>******");
		DemoCollection.traverseCollectionViaIterator(set);
		TreeSet<Person> ts = new TreeSet<Person>();
		ts.addAll(set);
		System.out.println("******TreeSet<Person>******");
		DemoCollection.traverseCollectionViaIterator(ts);
	}
	public static void testList(){
		System.out.println("******Testing List******");
		ArrayList<String> list = new ArrayList<String>();
		boolean b = list.add("Grade1");
		System.out.println(b);
		b=list.add("Grade2");
		System.out.println(b);
		b=list.add("Grade1");
		System.out.println(b);
		b=list.add(null);
		System.out.println(b);
		System.out.println(list);
		b=list.remove("Grade3");
		System.out.println(b);
		System.out.println(list);
		b=list.remove("Grade1");
		System.out.println(b);
		System.out.println(list);
		
		DemoCollection.traverseCollectionViaIterator(list);
		/*
		System.out.println("***Iterator***");
		int i = 0;
		for(Iterator<String> it = list.iterator(); it.hasNext();){			
			System.out.println((++i) + ": " + it.next());
		}
		*/
		list.clear();
		System.out.println(list);
	}
	public static void testSet(){
		System.out.println("******Testing Set******");
		HashSet<String> set = new HashSet<String>();
		boolean b = set.add("Grade1");
		System.out.println(b);
		b=set.add("Grade2");
		System.out.println(b);
		b=set.add("Grade1");
		System.out.println(b);
		b=set.add(null);
		System.out.println(b);
		System.out.println(set);
		b=set.remove("Grade3");
		System.out.println(b);
		System.out.println(set);
		b=set.remove(null);
		System.out.println(b);
		System.out.println(set);
		
		DemoCollection.traverseCollectionViaIterator(set);
		/*
		System.out.println("***Iterator***");
		int i = 0;
		for(Iterator<String> it = set.iterator(); it.hasNext();){			
			System.out.println((++i) + ": " + it.next());
		}
		*/
		set.clear();
		System.out.println(set);
	}
	public static void testMap(){
		System.out.println("******Testing Map******");
		HashMap<Integer, String> map = new HashMap<Integer, String>();
		String s = map.put(1, "Grade1");
		System.out.println(s);
		s = map.put(2, "Grade2");
		System.out.println(s);
		/*The return value is the previous value associated with key, or null if there was no mapping for key. 
		 * (A null return can also indicate that the map previously associated null with key.) 
		 */
		s = map.put(1, "Grade3");
		System.out.println(s);
		s = map.put(3, "Grade4");
		System.out.println(s);
		System.out.println(map);
		s = map.remove(4);
		System.out.println(s);
		System.out.println(map);
		s = map.remove(1);
		System.out.println(s);
		System.out.println(map);

		s = map.put(1, "Grade2");
		System.out.println(s);
		System.out.println(map);
		boolean b = map.remove(1, "Grade1");
		System.out.println(b);
		System.out.println(map);
		b = map.remove(2, "Grade2");
		System.out.println(b);
		System.out.println(map);
		
		DemoCollection.traverseMapViaIterator(map);
		/*
		System.out.println("***Iterator***");
		int i = 0;
		for(Iterator<Entry<Integer, String>> it = map.entrySet().iterator(); it.hasNext();){			
			//System.out.println((++i) + ": " + it.next());
			Entry<Integer, String> entry = it.next();
			System.out.print((++i) + ": ");
			System.out.print("key = " + entry.getKey() + ", ");
			System.out.println("value = " + entry.getValue());
		}
		System.out.println("***End of traversing***");
		*/
		map.clear();
		System.out.println(map);
	}
	public static <T> void traverseCollectionViaIterator(Collection<T> c){
		System.out.println("***Iterator***");
		int i = 0;
		for(Iterator<T> it = c.iterator(); it.hasNext();){			
			System.out.println((++i) + ": " + it.next());
		}
		System.out.println("***End of traversing***");
	}

	public static <T1, T2> void traverseMapViaIterator(Map<T1, T2> map){
		System.out.println("***Iterator***");
		int i = 0;
		for(Iterator<Entry<T1, T2>> it = map.entrySet().iterator(); it.hasNext();){			
			//System.out.println((++i) + ": " + it.next());			
			Entry<T1, T2> entry = it.next();
			System.out.print((++i) + ": ");
			System.out.print("key = " + entry.getKey() + ", ");
			System.out.println("value = " + entry.getValue());
			
		}
		System.out.println("***End of traversing***");
	}
}
class Person implements Comparable{
	String id;
	String name;
	Person(){super();}
	Person(String id, String name){
		this.id = id;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + "]";
	}
	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(this.id).toHashCode();
	}
	@Override
	public boolean equals(Object obj) {
		Person p = (Person)obj;
		return new EqualsBuilder()
				.append(this.id, p.id)/*.append(this.name, p.name)*/
				.isEquals();
	}	
/*
	@SuppressWarnings("unchecked")
	public <T> Class<T> getClazz(){
		return (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
*/
	@Override
	public int compareTo(Object o) {
		Person  p = (Person) o;
		return this.id.compareTo(p.id);
	}	
}
class ComparatorViaPersonId implements Comparator<Person>{
	@Override
	public int compare(Person o1, Person o2) {
		return o1.id.compareTo(o2.id);
	}
	
}
